import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// 数据管理类
class DataManager {
    private Map<String, User> users;
    private Map<String, Movie> movies;
    private Map<String, Hall> halls;
    private Map<String, Session> sessions;
    private Map<String, Ticket> tickets;
    private List<LogEntry> logs;

    public DataManager() {
        users = new HashMap<>();
        movies = new HashMap<>();
        halls = new HashMap<>();
        sessions = new HashMap<>();
        tickets = new HashMap<>();
        logs = new ArrayList<>();
        initializeDefaultData();
    }

    private void initializeDefaultData() {
        // 初始化管理员账户
        users.put("admin", new User("admin", "admin", "ynuinfo#777", "", UserRole.ADMIN));

        // 初始化放映厅
        halls.put("hall1", new Hall("hall1", "黄金厅", 8, 10));
        halls.put("hall2", new Hall("hall2", "白银厅", 10, 12));
        halls.put("hall3", new Hall("hall3", "翡翠厅", 7, 8));
        halls.put("hall4", new Hall("hall4", "钻石厅", 7, 8));
        halls.put("hall5", new Hall("hall5", "宝石厅", 8, 9));
    }

    // 用户管理
    public Map<String, User> getUsers() {
        return users;
    }

    public User getUser(String username) {
        return users.get(username);
    }

    public void addUser(User user) {
        users.put(user.getUsername(), user);
    }

    public void removeUser(String username) {
        users.remove(username);
    }

    // 影片管理
    public Map<String, Movie> getMovies() {
        return movies;
    }

    public Movie getMovie(String movieId) {
        return movies.get(movieId);
    }

    public void addMovie(Movie movie) {
        movies.put(movie.getMovieId(), movie);
    }

    public void removeMovie(String movieId) {
        movies.remove(movieId);
    }

    // 放映厅管理
    public Map<String, Hall> getHalls() {
        return halls;
    }

    public Hall getHall(String hallId) {
        return halls.get(hallId);
    }

    // 场次管理
    public Map<String, Session> getSessions() {
        return sessions;
    }

    public Session getSession(String sessionId) {
        return sessions.get(sessionId);
    }

    public void addSession(Session session) {
        sessions.put(session.getSessionId(), session);
    }

    public void removeSession(String sessionId) {
        sessions.remove(sessionId);
    }

    // 票务管理
    public Map<String, Ticket> getTickets() {
        return tickets;
    }

    public Ticket getTicket(String ticketId) {
        return tickets.get(ticketId);
    }

    public void addTicket(Ticket ticket) {
        tickets.put(ticket.getTicketId(), ticket);
    }

    public void removeTicket(String ticketId) {
        tickets.remove(ticketId);
    }

    // 日志管理
    public List<LogEntry> getLogs() {
        return logs;
    }

    public void addLog(LogEntry log) {
        logs.add(log);
    }

    // 根据时间筛选场次
    public List<Session> getSessionsByDateRange(LocalDateTime start, LocalDateTime end) {
        return sessions.values().stream()
                .filter(session -> !session.getStartTime().isBefore(start) &&
                        session.getStartTime().isBefore(end))
                .collect(Collectors.toList());
    }

    // 获取某场次的售票数量
    public int getSoldTicketsCount(String sessionId) {
        return (int) tickets.values().stream()
                .filter(ticket -> ticket.getSessionId().equals(sessionId) && !ticket.isRefunded())
                .count();
    }

    // 获取指定时间段的总售票数
    public int getSoldTicketsCount(LocalDateTime start, LocalDateTime end) {
        return (int) tickets.values().stream()
                .filter(ticket -> !ticket.isRefunded() &&
                        sessions.containsKey(ticket.getSessionId()))
                .filter(ticket -> {
                    Session session = sessions.get(ticket.getSessionId());
                    return !session.getStartTime().isBefore(start) &&
                            session.getStartTime().isBefore(end);
                })
                .count();
    }
}
